﻿namespace Exporter.Exporters.Implementations
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using DocumentFormat.OpenXml;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Wordprocessing;
    using MoviesDataBase;
    using A = DocumentFormat.OpenXml.Drawing;
    using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
    using PIC = DocumentFormat.OpenXml.Drawing.Pictures;

    /// <summary>
    /// Word export class.
    /// </summary>
    public class WordExport : IFileExporter
    {
        /// <summary>
        /// The part template.
        /// </summary>
        private const string TEMPLATE = "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" +
           "<w:document xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'>" +
           "<w:body>#REPLACE#</w:body></w:document>";

        /// <summary>
        /// Inserts the A picture.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="fileName">Name of the file.</param>
        public static void InsertAPicture(string document, string fileName)
        {
            using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Create(document, WordprocessingDocumentType.Document))
            {
                MainDocumentPart mainPart = wordprocessingDocument.AddMainDocumentPart();
                mainPart.Document = new Document()
                {
                    Body = new Body()
                };

                ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);

                try
                {
                    using (Stream stream = new MemoryStream(new WebClient().DownloadData(new Uri(fileName))))
                    {
                        imagePart.FeedData(stream);
                    }

                    AddImageToBody(wordprocessingDocument, mainPart.GetIdOfPart(imagePart));
                }
                catch
                {
                }
            }
        }

        /// <summary>
        /// Exports the specified filename.
        /// </summary>
        /// <param name="filename">The filename.</param>
        /// <param name="movies">The movies.</param>
        public void Export(string filename, IEnumerable<Movie> movies)
        {
            foreach (Movie m in movies)
            {
                InsertAPicture(filename, m.Poster);
            }
        }

        /// <summary>
        /// Adds the image to body.
        /// </summary>
        /// <param name="wordDoc">The word doc.</param>
        /// <param name="relationshipId">The relationship id.</param>
        private static void AddImageToBody(WordprocessingDocument wordDoc, string relationshipId)
        {
            // Define the reference of the image.
            var element =
                 new Drawing(
                     new DW.Inline(
                         new DW.Extent()
                         {
                             Cx = 990000L,
                             Cy = 792000L
                         },
                         new DW.EffectExtent()
                         {
                             LeftEdge = 0L,
                             TopEdge = 0L,
                             RightEdge = 0L,
                             BottomEdge = 0L
                         },
                         new DW.DocProperties()
                         {
                             Id = (UInt32Value)1U,
                             Name = "Picture 1"
                         },
                         new DW.NonVisualGraphicFrameDrawingProperties(
                             new A.GraphicFrameLocks() { NoChangeAspect = true }),
                         new A.Graphic(
                             new A.GraphicData(
                                 new Picture(
                                     new PIC.NonVisualPictureProperties(
                                         new PIC.NonVisualDrawingProperties()
                                         {
                                             Id = (UInt32Value)0U,
                                             Name = "New Bitmap Image.jpg"
                                         },
                                         new PIC.NonVisualPictureDrawingProperties()),
                                     new PIC.BlipFill(
                                         new A.Blip(
                                             new A.BlipExtensionList(
                                                 new A.BlipExtension()
                                                 {
                                                     Uri =
                                                       "{28A0092B-C50C-407E-A947-70E740481C1C}"
                                                 }))
                                         {
                                             Embed = relationshipId,
                                             CompressionState = A.BlipCompressionValues.Print
                                         },
                                         new A.Stretch(
                                             new A.FillRectangle())),
                                     new PIC.ShapeProperties(
                                         new A.Transform2D(
                                             new A.Offset() { X = 0L, Y = 0L },
                                             new A.Extents() { Cx = 990000L, Cy = 792000L }),
                                         new A.PresetGeometry(
                                             new A.AdjustValueList())
                                             {
                                                 Preset = A.ShapeTypeValues.Rectangle
                                             })))
                                         {
                                             Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture"
                                         }))
                     {
                         DistanceFromTop = (UInt32Value)0U,
                         DistanceFromBottom = (UInt32Value)0U,
                         DistanceFromLeft = (UInt32Value)0U,
                         DistanceFromRight = (UInt32Value)0U,
                         EditId = "50D07946"
                     });

            // Append the reference to body, the element should be in a Run.
            wordDoc.MainDocumentPart.Document.Body.AppendChild(new Paragraph(new Run(element)));
        }
    }
}
